/********************************************
 * 功能说明: RSA工具类
 * 模块名称: 通用工具模块
 * 系统名称: 互联网金融平台
 * 软件版权: 北京银杉金服科技有限公司
 * 系统版本: 1.0.0
 * 开发人员: zhaorq
 * 开发时间: 2016年12月23日 下午9:15:41
 * 审核人员:
 * 相关文档:
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.trade.common.utils.crypto;

import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * RSA工具类
 * @author zhaorq
 * @version 1.0.0.1
 */
public class RSAUtils {
	
	private static Map<String, RSAPublicKey> publicKeyMap = new HashMap<String, RSAPublicKey>();
	private static Map<String, RSAPrivateKey> privateKeyMap = new HashMap<String, RSAPrivateKey>();

	public static void main(String[] args) throws Exception {
		String filepath = "D:/tmp/";
		// 生成RSA秘钥文件
		//RSAEncrypt.genKeyPair(filepath);
		
		// 加载RSA秘钥文件
		String publicKeyStr = RSAEncrypt.loadPublicKeyByFile(filepath);
		String privateKeyStr = RSAEncrypt.loadPrivateKeyByFile(filepath);
		System.out.println("公钥：" + publicKeyStr);
		System.out.println("私钥：" + privateKeyStr);
		
		String content = privateKeyStr;
		String signStr = RSAUtils.sign(content, privateKeyStr);
		System.out.println("签名：" + signStr);
		
		boolean ret = RSAUtils.checkSign(publicKeyStr, content, signStr);
		System.out.println("验签：" + ret);
		
	}
	public static void main2(String[] args) throws Exception {
		String filepath = "D:/tmp/";
		// 生成RSA秘钥文件
		RSAEncrypt.genKeyPair(filepath);
		
		// 加载RSA秘钥文件
		String publicKeyStr = RSAEncrypt.loadPublicKeyByFile(filepath);
		String privateKeyStr = RSAEncrypt.loadPrivateKeyByFile(filepath);
		System.out.println("公钥：" + publicKeyStr);
		System.out.println("私钥：" + privateKeyStr);
		
		System.out.println("--------------公钥加密私钥解密过程-------------------");
		String plainText = "aghoo_公钥加密私钥解密";
		// 公钥加密
		String cipherText = RSAUtils.encryptByPublicKey(plainText, publicKeyStr);
		// 私钥解密
		String PlainText2 = RSAUtils.decryptByPrivateKey(cipherText, privateKeyStr);
		System.out.println("原文：" + plainText);
		System.out.println("密文：" + cipherText);
		System.out.println("解密：" + PlainText2);
		System.out.println();

		System.out.println("--------------私钥加密公钥解密过程-------------------");
		plainText = "aghoo_私钥加密公钥解密";
		// 私钥加密
		cipherText = RSAUtils.encryptByPrivateKey(plainText, privateKeyStr);
		// 公钥解密
		PlainText2 = RSAUtils.decryptByPublicKey(cipherText, publicKeyStr);
		System.out.println("原文：" + plainText);
		System.out.println("密文：" + cipherText);
		System.out.println("解密：" + PlainText2);
		System.out.println();

		System.out.println("---------------私钥签名过程------------------");
		String content = "aghoo_这是用于签名的原始数据";
		String signstr = RSASignature.sign(content, privateKeyStr);
		System.out.println("原文：" + content);
		System.out.println("签名：" + signstr);
		System.out.println();

		System.out.println("---------------公钥验签过程------------------");
		System.out.println("原文：" + content);
		System.out.println("签名：" + signstr);

		System.out.println("验签结果：" + RSASignature.checkSign(content, signstr, publicKeyStr));
		System.out.println();
	}
	
	/**
	 * 获取RSA公钥
	 * @param publicKeyStr
	 * @return
	 */
	public static RSAPublicKey getPublicKey(String publicKeyStr) throws Exception {
		RSAPublicKey publicKey = publicKeyMap.get(publicKeyStr);
		if (publicKey == null) {
			publicKey = RSAEncrypt.loadPublicKeyByStr(publicKeyStr);
			publicKeyMap.put(publicKeyStr, publicKey);
		}
		return publicKey;
	}
	
	/**
	 * 获取RSA私钥
	 * @param privateKeyStr
	 * @return
	 */
	public static RSAPrivateKey getPrivateKey(String privateKeyStr) throws Exception {
		RSAPrivateKey privateKey = privateKeyMap.get(privateKeyStr);
		if (privateKey == null) {
			privateKey = RSAEncrypt.loadPrivateKeyByStr(privateKeyStr);
			privateKeyMap.put(privateKeyStr, privateKey);
		}
		return privateKey;
	}
	
	/**
	 * RSA私钥加密
	 * @param privateKeyStr
	 * @param plainText
	 * @return
	 * @throws Exception
	 */
	public static String encryptByPrivateKey(String plainText, String privateKeyStr) throws Exception {
		RSAPrivateKey privateKey = getPrivateKey(privateKeyStr);
		return RSAEncrypt.encrypt(privateKey, plainText);
	}
	
	/**
	 * RSA公钥解密
	 * @param cipherText
	 * @param publicKeyStr
	 * @return
	 * @throws Exception
	 */
	public static String decryptByPublicKey(String cipherText, String publicKeyStr) throws Exception {
		RSAPublicKey publicKey = getPublicKey(publicKeyStr);
		return RSAEncrypt.decrypt(publicKey, cipherText);
	}
	
	/**
	 * RSA公钥加密
	 * @param plainText
	 * @param publicKeyStr
	 * @return
	 * @throws Exception
	 */
	public static String encryptByPublicKey(String plainText, String publicKeyStr) throws Exception {
		RSAPublicKey publicKey = getPublicKey(publicKeyStr);
		return RSAEncrypt.encrypt(publicKey, plainText);
	}
	
	/**
	 * RSA私钥解密
	 * @param cipherText
	 * @param privateKeyStr
	 * @return
	 * @throws Exception
	 */
	public static String decryptByPrivateKey(String cipherText, String privateKeyStr) throws Exception {
		RSAPrivateKey privateKey = getPrivateKey(privateKeyStr);
		return RSAEncrypt.decrypt(privateKey, cipherText);
	}
	
	/**
	 * RSA私钥签名
	 * @param content 待签名数据
	 * @param privateKeyStr RSA私钥
	 * @return 签名值
	 */
	public static String sign(String content, String privateKeyStr) throws Exception {
		return RSASignature.sign(content, privateKeyStr);
	}
	
	/**
	 * RSA公钥验签
	 * @param content 已签名数据
	 * @param signStr 签名值
	 * @param publicKeyStr RSA公钥
	 * @return 布尔值
	 */
	public static boolean checkSign(String publicKeyStr, String content, String signStr) {
		return RSASignature.checkSign(content, signStr, publicKeyStr);
	}

}
